package com.cac.demo.util.adapter;

import org.springframework.beans.BeanUtils;
import org.springframework.beans.BeansException;
import org.springframework.beans.FatalBeanException;
import org.springframework.util.Assert;
import org.springframework.util.ClassUtils;

import java.beans.PropertyDescriptor;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * @className: BeanUtil
 * @description: （描述这个类的作用）
 * @author:
 * @date: 2024/6/22 11:33:33 周六
 * @version: 1.0
 */
public class BeanUtil extends BeanUtils {

    private static final int BEAN_METHOD_PROP_INDEX = 3;
    private static final Pattern GET_PATTERN = Pattern.compile("get(\\p{javaUpperCase}\\w*)");
    private static final Pattern SET_PATTERN = Pattern.compile("set(\\p{javaUpperCase}\\w*)");

    public BeanUtil() {
    }

    public static void copyBeanProp(Object dest, Object src) {
        try {
            copyProperties(src, dest);
        } catch (Exception var3) {
            var3.printStackTrace();
        }

    }

    public static List<Method> getSetterMethods(Object obj) {
        List<Method> setterMethods = new ArrayList();
        Method[] methods = obj.getClass().getMethods();
        Method[] var3 = methods;
        int var4 = methods.length;

        for(int var5 = 0; var5 < var4; ++var5) {
            Method method = var3[var5];
            Matcher m = SET_PATTERN.matcher(method.getName());
            if (m.matches() && method.getParameterTypes().length == 1) {
                setterMethods.add(method);
            }
        }

        return setterMethods;
    }

    public static List<Method> getGetterMethods(Object obj) {
        List<Method> getterMethods = new ArrayList();
        Method[] methods = obj.getClass().getMethods();
        Method[] var3 = methods;
        int var4 = methods.length;

        for(int var5 = 0; var5 < var4; ++var5) {
            Method method = var3[var5];
            Matcher m = GET_PATTERN.matcher(method.getName());
            if (m.matches() && method.getParameterTypes().length == 0) {
                getterMethods.add(method);
            }
        }

        return getterMethods;
    }

    public static boolean isMethodPropEquals(String m1, String m2) {
        return m1.substring(3).equals(m2.substring(3));
    }

    public static void copyProperties(Object source, Object target, boolean skipNull) throws BeansException {
        copyProperties(source, target, skipNull, (String[])null);
    }

    public static void copyProperties(Object source, Object target, boolean skipNull, String... ignoreProperties) throws BeansException {
        Assert.notNull(source, "Source must not be null");
        Assert.notNull(target, "Target must not be null");
        PropertyDescriptor[] targetPds = getPropertyDescriptors(target.getClass());
        List<String> ignoreList = ignoreProperties != null ? Arrays.asList(ignoreProperties) : null;
        PropertyDescriptor[] var6 = targetPds;
        int var7 = targetPds.length;

        for(int var8 = 0; var8 < var7; ++var8) {
            PropertyDescriptor targetPd = var6[var8];
            Method writeMethod = targetPd.getWriteMethod();
            if (writeMethod != null && (ignoreList == null || !ignoreList.contains(targetPd.getName()))) {
                PropertyDescriptor sourcePd = getPropertyDescriptor(source.getClass(), targetPd.getName());
                if (sourcePd != null) {
                    Method readMethod = sourcePd.getReadMethod();
                    if (readMethod != null && ClassUtils.isAssignable(writeMethod.getParameterTypes()[0], readMethod.getReturnType())) {
                        try {
                            if (!Modifier.isPublic(readMethod.getDeclaringClass().getModifiers())) {
                                readMethod.setAccessible(true);
                            }

                            Object value = readMethod.invoke(source);
                            if (null != value || !skipNull) {
                                if (!Modifier.isPublic(writeMethod.getDeclaringClass().getModifiers())) {
                                    writeMethod.setAccessible(true);
                                }

                                writeMethod.invoke(target, value);
                            }
                        } catch (Throwable var14) {
                            throw new FatalBeanException("Could not copy property '" + targetPd.getName() + "' from source to target", var14);
                        }
                    }
                }
            }
        }

    }
}
